home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF Read/write CDFs.
- *
- * Version 1.0, 14-Feb-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 14-Feb-92, J Love Original version. These functions were taken
- * out of `cdflib.c'.
- *
- ******************************************************************************/
-
- #include "cdflib.h"
-
- #if defined(vms) /* THIS FUNCTIONS IS ONLY USED ON VMS SYSTEMS */
- /******************************************************************************
- * Read a CDF Version 1.1 header (.CDF & .CDH).
- *
- * Those lines marked N/A don't necessary apply to Version 1 CDFs but are
- * included to be consistent with the processing of V2.0+ CDFs.
- ******************************************************************************/
-
- CDFstatus read_V1_header (CDF)
- struct cdfSTRUCT *CDF;
- {
- char var_datatype[V1_DATATYPE_STRING_LEN+1];
- char attr_datatype[V1_DATATYPE_STRING_LEN+1];
- struct attrSTRUCT *Attr;
- struct entrySTRUCT *Entry;
- struct varSTRUCT *Var;
- long attrid;
- long entryid;
- long reclength;
- long NattrRecs;
- long i;
- long offset;
- long data_bytesize;
- long tmp;
- long attrRecN;
- long Nbytes;
- long possNrecs;
- long varNum;
- int stat;
- File *fp;
- CDFstatus Pstatus = CDF_OK; /* pending status */
- CDFstatus Tstatus; /* temporary status */
- CDFstatus status;
- char tmp_filename[CDF_PATHNAME_LEN+4+1]; /* +4+1 for .CDF/.CDH and
- NUL-terminator */
-
- /* Fill in CDF version 2 data structures with version 1 data */
-
- CDF->CDRoffset = 0; /* N/A */
- CDF->CDR.RecordSize = 0; /* N/A */
- CDF->CDR.RecordType = 0; /* N/A */
- CDF->CDR.GDRoffset = 0; /* N/A */
-
- CDF->CDR.Version = 1;
- CDF->CDR.Release = 1;
-
- CDF->CDR.Encoding = VAX_ENCODING;
-
- CDF->CDR.Flags = 0;
- clrbit(CDF->CDR.Flags,CDF_MAJORITY_BIT);
- clrbit(CDF->CDR.Flags,CDF_FORMAT_BIT);
-
- CDF->CDR.rfuA = 0; /* N/A */
- CDF->CDR.rfuB = 0; /* N/A */
-
- CDF->CDR.Increment = 0; /* always 0 for Version 1 CDFs */
-
- CDF->CDR.rfuD = -1; /* N/A */
- CDF->CDR.rfuE = -1; /* N/A */
-
- strcpy (CDF->CDR.copyright,
- "\nNo copyright text for a Version 1.1 CDF\n");
-
- /* Skip over Header Record */
- /* Skip over FDR's */
-
- Seek (CDF->fp, V1_GDR_OFFSET, SEEK_SET);
-
- /* Read in GDR record */
-
- CDF->GDRoffset = 0; /* N/A */
- CDF->GDR.RecordSize = 0; /* N/A */
- CDF->GDR.RecordType = 0; /* N/A */
- CDF->GDR.VDRhead = 0; /* N/A */
- CDF->GDR.garbage1 = 0; /* N/A */
- CDF->GDR.ADRhead = 0; /* N/A */
- CDF->GDR.eof = 0; /* N/A */
-
- CDF->GDR.rfuA = 0; /* N/A */
- CDF->GDR.rfuB = 0; /* N/A */
- CDF->GDR.rfuC = 0; /* N/A */
- CDF->GDR.rfuD = -1; /* N/A */
- CDF->GDR.rfuE = -1; /* N/A */
-
- CDF->GDR.DimSizes = (long *) malloc (V1_MAX_DIMS*sizeof(Int32));
- if (CDF->GDR.DimSizes == NULL) return BAD_MALLOC;
-
- for (i=0;i<V1_MAX_DIMS;i++)
- getint32H(CDF->fp,CDF->GDR.DimSizes[i]);
-
- getint32H(CDF->fp,CDF->GDR.NumDims);
- getint32H(CDF->fp,CDF->GDR.NumVar);
-
- getint32H(CDF->fp,tmp);
- CDF->GDR.MaxRec = tmp - 1;
-
- /* Seek to first VDR */
-
- if (CDF->GDR.NumVar > 0)
- Seek (CDF->fp, V1_FIRST_VDR_OFFSET, SEEK_SET);
-
- for(varNum=0;varNum<CDF->GDR.NumVar;varNum++){
- Var = (struct varSTRUCT *) malloc (sizeof(struct varSTRUCT));
- if (Var == NULL) return BAD_MALLOC;
-
- if (varNum == 0) {
- CDF->varHead = Var;
- CDF->varTail = Var;
- }
- else {
- CDF->varTail->varNext = Var;
- CDF->varTail = Var;
- }
-
- Var->varNext = (struct varSTRUCT *) NULL;
-
- Var->VDRoffset = 0; /* N/A */
- Var->vixHead = 0; /* N/A */
- Var->vixTail = 0; /* N/A */
-
- Var->VDR.RecordSize = 0; /* N/A */
- Var->VDR.RecordType = 0; /* N/A */
- Var->VDR.VDRnext = 0; /* N/A */
-
- getbytes (V1_DATATYPE_STRING_LEN, var_datatype, CDF->fp);
- var_datatype[V1_DATATYPE_STRING_LEN] = '\0';
- if(strcmp("INT*4 ",var_datatype) == 0)
- Var->VDR.DataType = CDF_INT4;
- else if(strcmp("REAL*8 ",var_datatype) == 0)
- Var->VDR.DataType = CDF_REAL8;
- else if(strcmp("REAL*4 ",var_datatype) == 0)
- Var->VDR.DataType = CDF_REAL4;
- else if(strcmp("STRING ",var_datatype) == 0)
- Var->VDR.DataType = CDF_CHAR;
- else if(strcmp("INT*2 ",var_datatype) == 0)
- Var->VDR.DataType = CDF_INT2;
- else if(strcmp("BYTE ",var_datatype) == 0)
- Var->VDR.DataType = CDF_BYTE;
- else
- return CORRUPTED_V1_CDF; /* CLEAN UP! */
-
- for (i=0;i<V1_MAX_DIMS;i++)
- getint32H(CDF->fp,tmp); /* skip dimension map */
-
- Var->VDR.VXRhead = 0; /* N/A */
- Var->VDR.VXRtail = 0; /* N/A */
-
- Var->VDR.Flags = 0;
- getint32H(CDF->fp,tmp);
-
- if (tmp)
- setbit(Var->VDR.Flags,VAR_RECVARY_BIT);
- else
- clrbit(Var->VDR.Flags,VAR_RECVARY_BIT);
-
- clrbit(Var->VDR.Flags,VAR_FILLVALUE_BIT); /* N/A */
-
- Var->VDR.rfuA = 0; /* N/A */
- Var->VDR.rfuB = 0; /* N/A */
- Var->VDR.rfuC = -1; /* N/A */
- Var->VDR.REFvarNum = -1; /* N/A */
- Var->VDR.REFfilename[0] = NUL; /* N/A */
-
- Var->VDR.DimVarys = (long *) malloc (V1_MAX_DIMS*sizeof(Int32));
- if (Var->VDR.DimVarys == NULL) return BAD_MALLOC;
-
- for (i = 0; i < V1_MAX_DIMS; i++) {
- getint32H(CDF->fp,tmp);
- if (tmp)
- Var->VDR.DimVarys[i] = VARY;
- else
- Var->VDR.DimVarys[i] = NOVARY;
- }
-
- getint32H(CDF->fp,tmp); /* skip variable rank */
-
- for (i=0;i<V1_MAX_DIMS;i++)
- getint32H(CDF->fp,tmp); /* skip products */
-
- getint32H(CDF->fp,tmp); /* skip total size */
- getint32H(CDF->fp,tmp); /* skip trans number*/
-
- getint32H(CDF->fp,Var->VDR.NumElem);
- if (Var->VDR.DataType != CDF_CHAR) Var->VDR.NumElem = 1;
-
- Var->VDR.rfuD = -1; /* N/A */
- Var->VDR.NextendRecs = 0; /* N/A */
- Var->VDR.FillValue = NULL; /* N/A */
-
- getbytes (V1_VAR_NAME_LEN, Var->VDR.Name, CDF->fp);
- Var->VDR.Name[V1_VAR_NAME_LEN] = NUL;
-
- /***************************************************************************
- * Check if data type should be changed to CDF_EPOCH.
- ***************************************************************************/
-
- #if NSSDC_STANDARD
- if (strcmpITB(Var->VDR.Name,"EPOCH") == 0 && Var->VDR.DataType == CDF_REAL8)
- Var->VDR.DataType = CDF_EPOCH;
- #endif
-
- Var->status = VAR_CLOSED; /* V1 CDFs are always MULTI */
-
- if (CDF->GDR.NumDims > 0) {
- Nbytes = CDF->GDR.NumDims * sizeof(long);
- Var->products = (long *) malloc (Nbytes);
- if (Var->products == NULL) return BAD_MALLOC;
- Var->hypProducts = (long *) malloc (Nbytes);
- if (Var->hypProducts == NULL) return BAD_MALLOC;
- Var->hypIndices = (long *) malloc (Nbytes);
- if (Var->hypIndices == NULL) return BAD_MALLOC;
- Var->hypTops = (long *) malloc (Nbytes);
- if (Var->hypTops == NULL) return BAD_MALLOC;
- }
- else {
- Var->products = NULL;
- Var->hypProducts = NULL;
- Var->hypIndices = NULL;
- Var->hypTops = NULL;
- }
-
- Var->seqValueOffset = 0;
-
- calcVarParms (CDF, Var);
-
- Var->VDR.Num = varNum;
-
- /******************************************************************************
- * The number of records per variable wasn't kept in Version 1 - this could
- * be a problem if not every variable (with TRUE record variance) has the
- * same number of records
- ******************************************************************************/
-
- #if GUESS_V1_VECTOR_SIZES
- if (bitset(Var->VDR.Flags,VAR_RECVARY_BIT))
- Var->VDR.MaxRec = CDF->GDR.MaxRec;
- else
- Var->VDR.MaxRec = (CDF->GDR.MaxRec == -1 ? -1 : 0);
- #else
- /***************************************************************************
- * Not guessing. Note that this algorithm isn't perfect (but I don't think
- * it can be improved either). If there is room for additional records in
- * the last block, they will be counted even if they were never actually
- * PUT. They won't be counted, however, if they are past the number of
- * records for the entire CDF (the only thing stored by CDF V1.1).
- *
- * Note also that the 'status' returned from opening the variable file isn't
- * returned to the caller if something went wrong. This is because some
- * CDF V1.1-based systems deleted empty vector files if Puts would never be
- * done to the associated variable. This way an error won't be reported to
- * the user until the variable is accessed (which shouldn't happen).
- ***************************************************************************/
-
- status = OpenVar (CDF, Var);
- if (status < CDF_WARN)
- Nbytes = 0;
- else {
- Seek (Var->fp, 0, SEEK_END);
- Nbytes = Tell (Var->fp); /* EOF offset = number of bytes in file */
- Close (Var->fp);
- }
- Var->status = VAR_CLOSED;
-
- possNrecs = Nbytes / Var->NphyRecBytes;
-
- if (bitset(Var->VDR.Flags,VAR_RECVARY_BIT))
- Var->VDR.MaxRec = Minimum (CDF->GDR.MaxRec, possNrecs - 1);
- else
- Var->VDR.MaxRec = Minimum (possNrecs - 1, 0);
- #endif
-
- CDF->var[varNum] = Var;
- }
-
- /* Now read CDH attribute file */
-
- /* Open CDH file */
-
- strcpy(tmp_filename,CDF->filename);
- strcat(tmp_filename,".cdh");
-
- fp = OpenFile (tmp_filename,"rb");
- if (fp == NULL) return CDH_OPEN_ERROR;
-
- getint32H(fp,NattrRecs);
- getint32H(fp,tmp); /* skip something */
- getint32H(fp,tmp); /* skip something */
- getint32H(fp,CDF->GDR.NumAttr);
-
- for (attrRecN = 0; attrRecN < NattrRecs-1; attrRecN++) {
- getint32H(fp,reclength);
- getint32H(fp,attrid);
- getint32H(fp,entryid);
- if(entryid == 0){
- /* Attribute Descriptor Record */
- Attr = (struct attrSTRUCT *) malloc (sizeof(struct attrSTRUCT));
- if (Attr == NULL) return BAD_MALLOC;
-
- if (CDF->attrHead == NULL) {
- CDF->attrHead = Attr;
- CDF->attrTail = Attr;
- }
- else {
- CDF->attrTail->attrNext = Attr;
- CDF->attrTail = Attr;
- }
-
- Attr->attrNext = (struct attrSTRUCT *) NULL;
-
- Attr->ADRoffset = 0; /* N/A */
- Attr->ADR.RecordSize = 0; /* N/A */
- Attr->ADR.RecordType = 0; /* N/A */
- Attr->ADR.ADRnext = 0; /* N/A */
- Attr->ADR.AEDRhead = 0; /* N/A */
-
- Attr->ADR.Num = attrid - 1;
-
- getint32H(fp,Attr->V1numBytes);
-
- getint32H(fp,tmp);
- Attr->ADR.MaxEntry = tmp - 1;
-
- Attr->ADR.NumEntries = 0; /* this will be incremented as
- AEDRs are read */
-
- Attr->ADR.rfuA = 0; /* N/A */
- Attr->ADR.rfuB = 0; /* N/A */
- Attr->ADR.rfuC = 0; /* N/A */
- Attr->ADR.rfuD = -1; /* N/A */
- Attr->ADR.rfuE = -1; /* N/A */
-
- if (Attr->ADR.MaxEntry == 0)
- Attr->ADR.Scope = GLOBAL_SCOPE_ASSUMED;
- else
- Attr->ADR.Scope = VARIABLE_SCOPE_ASSUMED;
-
- getbytes (V1_ATTR_NAME_LEN, Attr->ADR.Name, fp);
- Attr->ADR.Name[V1_ATTR_NAME_LEN] = NUL;
-
- getbytes (V1_DATATYPE_STRING_LEN, attr_datatype, fp);
- attr_datatype[V1_DATATYPE_STRING_LEN] = '\0';
-
- if (strcmp("INT*4 ",attr_datatype) == 0)
- Attr->V1dataType = CDF_INT4;
- else if(strcmp("REAL*8 ",attr_datatype) == 0)
- Attr->V1dataType = CDF_REAL8;
- else if(strcmp("REAL*4 ",attr_datatype) == 0)
- Attr->V1dataType = CDF_REAL4;
- else if(strcmp("STRING ",attr_datatype) == 0)
- Attr->V1dataType = CDF_CHAR;
- else if(strcmp("INT*2 ",attr_datatype) == 0)
- Attr->V1dataType = CDF_INT2;
- else if(strcmp("BYTE ",attr_datatype) == 0)
- Attr->V1dataType = CDF_BYTE;
- else
- return CORRUPTED_V1_CDF;
-
- Attr->entryHead = NULL;
- Attr->entryTail = NULL;
- }
- else {
- /* Must be an attribute record */
-
- /* First find corresponding attribute descriptor record */
-
- Attr = CDF->attrHead;
- while (Attr != NULL) {
- if (Attr->ADR.Num == attrid - 1) break;
- Attr = Attr->attrNext;
- }
- if (Attr == NULL) return CORRUPTED_V1_CDF;
-
- Entry = (struct entrySTRUCT *) malloc (sizeof(struct entrySTRUCT));
- if (Entry == NULL) return BAD_MALLOC;
-
- if (Attr->entryHead == NULL) {
- Attr->entryHead = Entry;
- Attr->entryTail = Entry;
- }
- else {
- Attr->entryTail->entryNext = Entry;
- Attr->entryTail = Entry;
- }
-
- Entry->entryNext = (struct entrySTRUCT *) NULL;
-
- Entry->AEDRoffset = 0; /* N/A */
- Entry->AEDR.RecordSize = 0; /* N/A */
- Entry->AEDR.RecordType = 0; /* N/A */
- Entry->AEDR.AEDRnext = 0; /* N/A */
-
- /* fill in attribute value record */
-
- Entry->AEDR.AttrNum = attrid - 1;
- Entry->AEDR.DataType = Attr->V1dataType;
- Entry->AEDR.Num = entryid - 1;
-
- Attr->ADR.NumEntries++; /* tally an attribute entry */
-
- if(Entry->AEDR.DataType == CDF_CHAR)
- Entry->AEDR.NumElem = Attr->V1numBytes;
- else
- Entry->AEDR.NumElem = 1;
-
- Entry->AEDR.rfuA = 0; /* N/A */
- Entry->AEDR.rfuB = 0; /* N/A */
- Entry->AEDR.rfuC = 0; /* N/A */
- Entry->AEDR.rfuD = -1; /* N/A */
- Entry->AEDR.rfuE = -1; /* N/A */
-
- Entry->AEDR.Value = (void *) malloc (Attr->V1numBytes);
- if (Entry->AEDR.Value == NULL) return BAD_MALLOC;
-
- getbytes (Attr->V1numBytes, Entry->AEDR.Value, fp);
-
- /***************************************************************************
- * Check if entry data type should be changed to CDF_EPOCH. Note that the
- * data type of the "EPOCH" variable will have already been changed to
- * CDF_EPOCH.
- ***************************************************************************/
-
- #if NSSDC_STANDARD
- if ((strcmpITB(Attr->ADR.Name,"VALIDMIN") == 0 ||
- strcmpITB(Attr->ADR.Name,"VALIDMAX") == 0 ||
- strcmpITB(Attr->ADR.Name,"SCALEMIN") == 0 ||
- strcmpITB(Attr->ADR.Name,"SCALEMAX") == 0) &&
- Entry->AEDR.DataType == CDF_REAL8) {
- Var = CDF->var[Entry->AEDR.Num];
- if (Var != NULL)
- if (Var->VDR.DataType == CDF_EPOCH) Entry->AEDR.DataType = CDF_EPOCH;
- }
- #endif
-
- }
- }
-
- /* close .CDH (.CDF stays open just like V2 CDFs) */
-
- stat = Close (fp);
- if (stat == EOF) return CDH_CLOSE_ERROR;
-
- return Pstatus;
- }
- #endif
-
- /******************************************************************************
- * Read a CDF Version 2.0/2.1 header (.CDF).
- ******************************************************************************/
-
- CDFstatus read_V2_header (CDF)
- struct cdfSTRUCT *CDF;
- {
- struct attrSTRUCT *Attr;
- struct entrySTRUCT *Entry;
- struct varSTRUCT *Var;
- struct vixSTRUCT *Vix;
- long data_bytesize,Nbytes;
- long VXRi,VDRi,ADRi,AEDRi;
- CDFstatus Pstatus = CDF_OK;
- long dimN;
- long i;
-
- /*** Fill in CDR ***/
-
- CDF->CDRoffset = V2_CDR_OFFSET;
- Seek (CDF->fp, CDF->CDRoffset, SEEK_SET);
-
- getint32(CDF->fp,CDF->CDR.RecordSize);
- getint32(CDF->fp,CDF->CDR.RecordType);
- if(CDF->CDR.RecordType != CDR_) return CORRUPTED_V2_CDF; /* CLEAN UP! */
-
- getint32(CDF->fp,CDF->CDR.GDRoffset);
- getint32(CDF->fp,CDF->CDR.Version);
- getint32(CDF->fp,CDF->CDR.Release);
-
- getint32(CDF->fp,CDF->CDR.Encoding);
-
- if (CDF->CDR.Encoding != NETWORK_ENCODING &&
- CDF->CDR.Encoding != _CDFhostEncoding) {
- switch (CDF->CDR.Encoding) {
- case VAX_ENCODING: return VAX_ENCODING_UNSUPPORTED;
- case SUN_ENCODING: return SUN_ENCODING_UNSUPPORTED;
- case MIPSEB_ENCODING: return MIPSEB_ENCODING_UNSUPPORTED;
- case MIPSEL_ENCODING: return MIPSEL_ENCODING_UNSUPPORTED;
- case IBMPC_ENCODING: return IBMPC_ENCODING_UNSUPPORTED;
- case IBMRS_ENCODING: return IBMRS_ENCODING_UNSUPPORTED;
- case HP_ENCODING: return HP_ENCODING_UNSUPPORTED;
- default: return CORRUPTED_V2_CDF;
- }
- }
-
- getint32(CDF->fp,CDF->CDR.Flags);
- getint32(CDF->fp,CDF->CDR.rfuA);
- getint32(CDF->fp,CDF->CDR.rfuB);
- getint32(CDF->fp,CDF->CDR.Increment);
- getint32(CDF->fp,CDF->CDR.rfuD);
- getint32(CDF->fp,CDF->CDR.rfuE);
-
- getbytes(CDF_COPYRIGHT_LEN,CDF->CDR.copyright,CDF->fp);
-
- /* Fill in GDR data structure */
-
- CDF->GDRoffset = CDF->CDR.GDRoffset;
- Seek (CDF->fp, CDF->GDRoffset, SEEK_SET);
-
- getint32(CDF->fp,CDF->GDR.RecordSize);
- getint32(CDF->fp,CDF->GDR.RecordType);
- if(CDF->GDR.RecordType != GDR_) return CORRUPTED_V2_CDF; /* CLEAN UP! */
-
- getint32(CDF->fp,CDF->GDR.VDRhead);
- getint32(CDF->fp,CDF->GDR.garbage1);
- getint32(CDF->fp,CDF->GDR.ADRhead);
- getint32(CDF->fp,CDF->GDR.eof); /* random value if V2.0 CDF */
- getint32(CDF->fp,CDF->GDR.NumVar);
- getint32(CDF->fp,CDF->GDR.NumAttr);
- getint32(CDF->fp,CDF->GDR.MaxRec);
- getint32(CDF->fp,CDF->GDR.NumDims);
- getint32(CDF->fp,CDF->GDR.rfuA);
- getint32(CDF->fp,CDF->GDR.rfuB);
- getint32(CDF->fp,CDF->GDR.rfuC);
- getint32(CDF->fp,CDF->GDR.rfuD);
- getint32(CDF->fp,CDF->GDR.rfuE);
-
- if (CDF->GDR.NumDims > 0) {
- CDF->GDR.DimSizes = (Int32 *) malloc (CDF->GDR.NumDims * sizeof(Int32));
- if (CDF->GDR.DimSizes == NULL) return BAD_MALLOC;
- }
- else
- CDF->GDR.DimSizes = NULL;
-
- for (dimN = 0; dimN < CDF->GDR.NumDims; dimN++)
- getint32(CDF->fp,CDF->GDR.DimSizes[dimN]);
-
- /* Read in VDRs - EXPLAIN PROBLEM WITH V2.0 OFFSETS */
-
- for (VDRi = 0; VDRi < CDF->GDR.NumVar; VDRi++) {
- Var = (struct varSTRUCT *) malloc (sizeof(struct varSTRUCT));
- if (Var == NULL) return BAD_MALLOC;
-
- if (VDRi == 0) {
- Var->VDRoffset = CDF->GDR.VDRhead;
- CDF->varHead = Var;
- CDF->varTail = Var;
- }
- else {
- Var->VDRoffset = CDF->varTail->VDR.VDRnext;
- CDF->varTail->varNext = Var;
- CDF->varTail = Var;
- }
-
- Var->varNext = (struct varSTRUCT *) NULL;
-
- Seek (CDF->fp, Var->VDRoffset, SEEK_SET);
-
- if (bitclr(CDF->CDR.Flags,CDF_FORMAT_BIT))
- Var->status = VAR_CLOSED;
- else
- Var->status = NO_VAR_FILE;
-
- getint32(CDF->fp,Var->VDR.RecordSize);
- getint32(CDF->fp,Var->VDR.RecordType);
- if(Var->VDR.RecordType != VDR_) return CORRUPTED_V2_CDF; /* CLEAN UP! */
-
- getint32(CDF->fp,Var->VDR.VDRnext);
- getint32(CDF->fp,Var->VDR.DataType);
- getint32(CDF->fp,Var->VDR.MaxRec);
- getint32(CDF->fp,Var->VDR.VXRhead);
- getint32(CDF->fp,Var->VDR.VXRtail);
- getint32(CDF->fp,Var->VDR.Flags);
- getint32(CDF->fp,Var->VDR.rfuA);
- getint32(CDF->fp,Var->VDR.rfuB);
- getint32(CDF->fp,Var->VDR.rfuC);
- getint32(CDF->fp,Var->VDR.REFvarNum);
-
- getbytes(CDF_VAR_FILE_NAME_LEN,Var->VDR.REFfilename,CDF->fp);
- Var->VDR.REFfilename[CDF_VAR_FILE_NAME_LEN] = NUL;
-
- getint32(CDF->fp,Var->VDR.NumElem);
- getint32(CDF->fp,Var->VDR.Num);
- getint32(CDF->fp,Var->VDR.rfuD);
- getint32(CDF->fp,Var->VDR.NextendRecs);
-
- getbytes(CDF_VAR_NAME_LEN,Var->VDR.Name,CDF->fp);
- Var->VDR.Name[CDF_VAR_NAME_LEN] = NUL;
-
- if (CDF->GDR.NumDims > 0) {
- Var->VDR.DimVarys = (Int32 *) malloc (CDF->GDR.NumDims * sizeof(Int32));
- if (Var->VDR.DimVarys == NULL) return BAD_MALLOC; /* CLEAN UP! */
- for (dimN = 0; dimN < CDF->GDR.NumDims; dimN++)
- getint32(CDF->fp,Var->VDR.DimVarys[dimN]);
- }
- else
- Var->VDR.DimVarys = NULL;
-
- if (bitset(Var->VDR.Flags,VAR_FILLVALUE_BIT)) {
- /*** can't use NvalueBytes - not calculated yet ***/
- Var->VDR.FillValue = (void *) malloc (Var->VDR.NumElem *
- _CDFelemSizes[Var->VDR.DataType]);
- if (Var->VDR.FillValue == NULL) return BAD_MALLOC;
- getbytes (Var->VDR.NumElem * _CDFelemSizes[Var->VDR.DataType],
- Var->VDR.FillValue, CDF->fp);
- DecodeBuffer (CDF->CDR.Encoding, Var->VDR.DataType,
- Var->VDR.NumElem, Var->VDR.FillValue);
- }
- else
- Var->VDR.FillValue = NULL;
-
- /***************************************************************************
- * Check if data type should be changed to CDF_EPOCH.
- ***************************************************************************/
-
- #if NSSDC_STANDARD
- if (CDF->CDR.Release == 0 ||
- (CDF->CDR.Release == 1 && CDF->CDR.Increment < 1))
- if (strcmpITB(Var->VDR.Name,"EPOCH") == 0 &&
- (Var->VDR.DataType == CDF_REAL8 || Var->VDR.DataType == CDF_DOUBLE))
- Var->VDR.DataType = CDF_EPOCH;
- #endif
-
- if (CDF->GDR.NumDims > 0) {
- Nbytes = CDF->GDR.NumDims * sizeof(Int32);
- Var->products = (long *) malloc (Nbytes);
- if (Var->products == NULL) return BAD_MALLOC;
- Var->hypProducts = (long *) malloc (Nbytes);
- if (Var->hypProducts == NULL) return BAD_MALLOC;
- Var->hypIndices = (long *) malloc (Nbytes);
- if (Var->hypIndices == NULL) return BAD_MALLOC;
- Var->hypTops = (long *) malloc (Nbytes);
- if (Var->hypTops == NULL) return BAD_MALLOC;
- }
- else {
- Var->products = NULL;
- Var->hypProducts = NULL;
- Var->hypIndices = NULL;
- Var->hypTops = NULL;
- }
-
- Var->seqValueOffset = 0;
-
- calcVarParms (CDF, Var);
-
- /*** if this is a SINGLE file CDF, set the Var's fp to that of the CDF ***/
-
- if (bitset(CDF->CDR.Flags,CDF_FORMAT_BIT))
- Var->fp = CDF->fp;
- else
- Var->fp = NULL;
-
- CDF->var[Var->VDR.Num] = Var;
-
- /*** read linked list of VXRs ***/
-
- Var->vixHead = (struct vixSTRUCT *) NULL;
- Var->vixTail = (struct vixSTRUCT *) NULL;
-
- if (bitset(CDF->CDR.Flags,CDF_FORMAT_BIT))
- if (Var->VDR.VXRhead != 0)
- for (VXRi = 0; /*continue until 'break'*/; VXRi++) {
- Vix = (struct vixSTRUCT *) malloc (sizeof(struct vixSTRUCT));
- if (Vix == NULL) return BAD_MALLOC;
-
- if (VXRi == 0) {
- Vix->VXRoffset = Var->VDR.VXRhead;
- Var->vixHead = Vix;
- Var->vixTail = Vix;
- }
- else {
- Vix->VXRoffset = Var->vixTail->VXR.VXRnext;
- Var->vixTail->vixNext = Vix;
- Var->vixTail = Vix;
- }
-
- Vix->vixNext = (struct vixSTRUCT *) NULL;
-
- Seek (CDF->fp, Vix->VXRoffset, SEEK_SET);
-
- getint32 (CDF->fp, Vix->VXR.RecordSize);
- getint32 (CDF->fp, Vix->VXR.RecordType);
- if (Vix->VXR.RecordType != VXR_)
- return CORRUPTED_V2_CDF; /* CLEAN UP! */
-
- getint32 (CDF->fp, Vix->VXR.VXRnext);
- getint32 (CDF->fp, Vix->VXR.Nentries);
- getint32 (CDF->fp, Vix->VXR.NusedEntries);
-
- Nbytes = Vix->VXR.Nentries * sizeof(Int32);
- Vix->VXR.FirstRec = (Int32 *) malloc (Nbytes);
- if (Vix->VXR.FirstRec == NULL) return BAD_MALLOC;
- Vix->VXR.LastRec = (Int32 *) malloc (Nbytes);
- if (Vix->VXR.LastRec == NULL) return BAD_MALLOC;
- Vix->VXR.VVRoffset = (Int32 *) malloc (Nbytes);
- if (Vix->VXR.VVRoffset == NULL) return BAD_MALLOC;
-
- for (i = 0; i < Vix->VXR.Nentries; i++)
- getint32 (CDF->fp, Vix->VXR.FirstRec[i]);
- for (i = 0; i < Vix->VXR.Nentries; i++)
- getint32 (CDF->fp, Vix->VXR.LastRec[i]);
- for (i = 0; i < Vix->VXR.Nentries; i++)
- getint32 (CDF->fp, Vix->VXR.VVRoffset[i]);
-
- if (Vix->VXR.VXRnext == 0) break;
- }
- }
-
- /* Read in Attribute Descriptors - EXPLAIN PROBLEM WITH V2.0 OFFSETS */
-
- for (ADRi = 0; ADRi < CDF->GDR.NumAttr; ADRi++) {
- Attr = (struct attrSTRUCT *) malloc (sizeof(struct attrSTRUCT));
- if (Attr == NULL) return BAD_MALLOC;
-
- if (ADRi == 0) {
- Attr->ADRoffset = CDF->GDR.ADRhead;
- CDF->attrHead = Attr;
- CDF->attrTail = Attr;
- }
- else {
- Attr->ADRoffset = CDF->attrTail->ADR.ADRnext;
- CDF->attrTail->attrNext = Attr;
- CDF->attrTail = Attr;
- }
-
- Attr->attrNext = (struct attrSTRUCT *) NULL;
-
- Seek (CDF->fp, Attr->ADRoffset, SEEK_SET);
-
- getint32(CDF->fp,Attr->ADR.RecordSize);
- getint32(CDF->fp,Attr->ADR.RecordType);
- if(Attr->ADR.RecordType != ADR_) return CORRUPTED_V2_CDF; /* CLEAN UP! */
-
- getint32(CDF->fp,Attr->ADR.ADRnext);
- getint32(CDF->fp,Attr->ADR.AEDRhead);
- getint32(CDF->fp,Attr->ADR.Scope);
- getint32(CDF->fp,Attr->ADR.Num);
- getint32(CDF->fp,Attr->ADR.NumEntries);
- getint32(CDF->fp,Attr->ADR.MaxEntry);
- getint32(CDF->fp,Attr->ADR.rfuA);
- getint32(CDF->fp,Attr->ADR.rfuB);
- getint32(CDF->fp,Attr->ADR.rfuC);
- getint32(CDF->fp,Attr->ADR.rfuD);
- getint32(CDF->fp,Attr->ADR.rfuE);
-
- getbytes(CDF_ATTR_NAME_LEN,Attr->ADR.Name,CDF->fp);
- Attr->ADR.Name[CDF_ATTR_NAME_LEN] = NUL;
-
- /*** read in AEDRs - EXPLAIN PROBLEM WITH V2.0 OFFSETS ***/
-
- Attr->entryHead = NULL;
- Attr->entryTail = NULL;
-
- for (AEDRi = 0; AEDRi < Attr->ADR.NumEntries; AEDRi++) {
- Entry = (struct entrySTRUCT *) malloc (sizeof(struct entrySTRUCT));
- if (Entry == NULL) return BAD_MALLOC;
-
- if (AEDRi == 0) {
- Entry->AEDRoffset = Attr->ADR.AEDRhead;
- Attr->entryHead = Entry;
- Attr->entryTail = Entry;
- }
- else {
- Entry->AEDRoffset = Attr->entryTail->AEDR.AEDRnext;
- Attr->entryTail->entryNext = Entry;
- Attr->entryTail = Entry;
- }
-
- Entry->entryNext = (struct entrySTRUCT *) NULL;
-
- Seek (CDF->fp, Entry->AEDRoffset, SEEK_SET);
-
- getint32(CDF->fp,Entry->AEDR.RecordSize);
- getint32(CDF->fp,Entry->AEDR.RecordType);
- if (Entry->AEDR.RecordType != AEDR_)
- return CORRUPTED_V2_CDF; /* CLEAN UP!*/
-
- getint32(CDF->fp,Entry->AEDR.AEDRnext);
- getint32(CDF->fp,Entry->AEDR.AttrNum);
- getint32(CDF->fp,Entry->AEDR.DataType);
- getint32(CDF->fp,Entry->AEDR.Num);
- getint32(CDF->fp,Entry->AEDR.NumElem);
- getint32(CDF->fp,Entry->AEDR.rfuA);
- getint32(CDF->fp,Entry->AEDR.rfuB);
- getint32(CDF->fp,Entry->AEDR.rfuC);
- getint32(CDF->fp,Entry->AEDR.rfuD);
- getint32(CDF->fp,Entry->AEDR.rfuE);
-
- data_bytesize = _CDFelemSizes[Entry->AEDR.DataType] *
- Entry->AEDR.NumElem;
- Entry->AEDR.Value = (void *) malloc (data_bytesize);
- if (Entry->AEDR.Value == NULL) return BAD_MALLOC;
-
- getbytes(data_bytesize,Entry->AEDR.Value,CDF->fp);
-
- DecodeBuffer (CDF->CDR.Encoding, Entry->AEDR.DataType,
- Entry->AEDR.NumElem, Entry->AEDR.Value);
-
- /************************************************************************
- * Check if entry data type should be changed to CDF_EPOCH. Note that
- * that data type of the "EPOCH" variable will have already been changed
- * to CDF_EPOCH.
- ************************************************************************/
-
- #if NSSDC_STANDARD
- if (CDF->CDR.Release == 0 ||
- (CDF->CDR.Release == 1 && CDF->CDR.Increment < 1))
- if ((strcmpITB(Attr->ADR.Name,"VALIDMIN") == 0 ||
- strcmpITB(Attr->ADR.Name,"VALIDMAX") == 0 ||
- strcmpITB(Attr->ADR.Name,"SCALEMIN") == 0 ||
- strcmpITB(Attr->ADR.Name,"SCALEMAX") == 0) &&
- (Entry->AEDR.DataType == CDF_REAL8 ||
- Entry->AEDR.DataType == CDF_DOUBLE)) {
- Var = CDF->var[Entry->AEDR.Num];
- if (Var != NULL)
- if (Var->VDR.DataType == CDF_EPOCH)
- Entry->AEDR.DataType = CDF_EPOCH;
- }
- #endif
- }
- }
-
- if (CDF->CDR.Release == 0) calc_V20_eof (CDF); /* necessary for V2.0
- CDFs only */
- return Pstatus;
- }
-
- /******************************************************************************
- * Write a CDF Version 2.0 header (.CDF).
- ******************************************************************************/
-
- CDFstatus write_V2_header (CDF)
- struct cdfSTRUCT *CDF;
- {
- struct attrSTRUCT *Attr;
- struct entrySTRUCT *Entry;
- struct varSTRUCT *Var;
- struct vixSTRUCT *Vix;
- long Nbytes;
- CDFstatus Pstatus = CDF_OK;
- long i;
- long dimN;
-
- /* Write out magic number(s) */
-
- Seek (CDF->fp, V2_MAGIC_OFFSET, SEEK_SET);
- putint32(CDF->fp,CDF->magic_number);
- putint32(CDF->fp,CDF->magic_number);
-
- /* Write out CDR */
-
- Seek (CDF->fp, CDF->CDRoffset, SEEK_SET);
- putint32(CDF->fp,CDF->CDR.RecordSize);
- putint32(CDF->fp,CDF->CDR.RecordType);
- putint32(CDF->fp,CDF->CDR.GDRoffset);
-
- CDF->CDR.Version = CDF_LIBRARY_VERSION;
- putint32(CDF->fp,CDF->CDR.Version);
-
- CDF->CDR.Release = CDF_LIBRARY_RELEASE;
- putint32(CDF->fp,CDF->CDR.Release);
-
- putint32(CDF->fp,CDF->CDR.Encoding);
- putint32(CDF->fp,CDF->CDR.Flags);
- putint32(CDF->fp,CDF->CDR.rfuA);
- putint32(CDF->fp,CDF->CDR.rfuB);
-
- CDF->CDR.Increment = CDF_LIBRARY_INCREMENT;
- putint32(CDF->fp,CDF->CDR.Increment);
-
- putint32(CDF->fp,CDF->CDR.rfuD);
- putint32(CDF->fp,CDF->CDR.rfuE);
-
- putbytes(CDF_COPYRIGHT_LEN, CDF->CDR.copyright, CDF->fp);
-
- /* Write out GDR */
-
- Seek (CDF->fp, CDF->GDRoffset, SEEK_SET);
- putint32(CDF->fp,CDF->GDR.RecordSize);
- putint32(CDF->fp,CDF->GDR.RecordType);
- putint32(CDF->fp,CDF->GDR.VDRhead);
- putint32(CDF->fp,CDF->GDR.garbage1);
- putint32(CDF->fp,CDF->GDR.ADRhead);
- putint32(CDF->fp,CDF->GDR.eof);
- putint32(CDF->fp,CDF->GDR.NumVar);
- putint32(CDF->fp,CDF->GDR.NumAttr);
- putint32(CDF->fp,CDF->GDR.MaxRec);
- putint32(CDF->fp,CDF->GDR.NumDims);
- putint32(CDF->fp,CDF->GDR.rfuA);
- putint32(CDF->fp,CDF->GDR.rfuB);
- putint32(CDF->fp,CDF->GDR.rfuC);
- putint32(CDF->fp,CDF->GDR.rfuD);
- putint32(CDF->fp,CDF->GDR.rfuE);
-
- for (dimN = 0; dimN < CDF->GDR.NumDims; dimN++)
- putint32(CDF->fp,CDF->GDR.DimSizes[dimN]);
-
- /* Write out VDRs */
-
- Var = CDF->varHead;
-
- while (Var != NULL) {
- Seek (CDF->fp, Var->VDRoffset, SEEK_SET);
-
- putint32(CDF->fp,Var->VDR.RecordSize);
- putint32(CDF->fp,Var->VDR.RecordType);
- putint32(CDF->fp,Var->VDR.VDRnext);
- putint32(CDF->fp,Var->VDR.DataType);
- putint32(CDF->fp,Var->VDR.MaxRec);
- putint32(CDF->fp,Var->VDR.VXRhead);
- putint32(CDF->fp,Var->VDR.VXRtail);
- putint32(CDF->fp,Var->VDR.Flags);
- putint32(CDF->fp,Var->VDR.rfuA);
- putint32(CDF->fp,Var->VDR.rfuB);
- putint32(CDF->fp,Var->VDR.rfuC);
- putint32(CDF->fp,Var->VDR.REFvarNum);
-
- putbytes(CDF_VAR_FILE_NAME_LEN, Var->VDR.REFfilename, CDF->fp);
-
- putint32(CDF->fp,Var->VDR.NumElem);
- putint32(CDF->fp,Var->VDR.Num);
- putint32(CDF->fp,Var->VDR.rfuD);
- putint32(CDF->fp,Var->VDR.NextendRecs);
-
- putbytes(CDF_VAR_NAME_LEN, Var->VDR.Name, CDF->fp);
-
- for (dimN = 0; dimN < CDF->GDR.NumDims; dimN++)
- putint32(CDF->fp,Var->VDR.DimVarys[dimN]);
-
- if (bitset(Var->VDR.Flags,VAR_FILLVALUE_BIT)) {
- #if defined(sun) | defined(MIPSEB) | defined(IBMRS) | defined(HP)
- /* Do nothing. */
- #endif
- #if defined(vax) | defined(MIPSEL) | defined(__IBMPC__)
- if (CDF->CDR.Encoding == NETWORK_ENCODING)
- xdr_encode (Var->VDR.DataType, Var->VDR.NumElem,
- Var->VDR.FillValue, Var->VDR.FillValue);
- #endif
- putbytes (Var->VDR.NumElem * _CDFelemSizes[Var->VDR.DataType],
- Var->VDR.FillValue, CDF->fp);
- }
-
- /* write out VXRs */
-
- Vix = Var->vixHead;
-
- while (Vix != NULL) {
- Seek (CDF->fp, Vix->VXRoffset, SEEK_SET);
-
- putint32(CDF->fp,Vix->VXR.RecordSize);
- putint32(CDF->fp,Vix->VXR.RecordType);
- putint32(CDF->fp,Vix->VXR.VXRnext);
- putint32(CDF->fp,Vix->VXR.Nentries);
- putint32(CDF->fp,Vix->VXR.NusedEntries);
-
- for (i = 0; i < Vix->VXR.Nentries; i++)
- putint32(CDF->fp,Vix->VXR.FirstRec[i]);
- for (i = 0; i < Vix->VXR.Nentries; i++)
- putint32(CDF->fp,Vix->VXR.LastRec[i]);
- for (i = 0; i < Vix->VXR.Nentries; i++)
- putint32(CDF->fp,Vix->VXR.VVRoffset[i]);
-
- Vix = Vix->vixNext;
- }
-
- Var = Var->varNext;
- }
-
- /* Write out ADRs and AEDRs */
-
- Attr = CDF->attrHead;
- while (Attr != NULL) {
- Seek (CDF->fp, Attr->ADRoffset, SEEK_SET);
- putint32(CDF->fp,Attr->ADR.RecordSize);
- putint32(CDF->fp,Attr->ADR.RecordType);
- putint32(CDF->fp,Attr->ADR.ADRnext);
- putint32(CDF->fp,Attr->ADR.AEDRhead);
- putint32(CDF->fp,Attr->ADR.Scope);
- putint32(CDF->fp,Attr->ADR.Num);
- putint32(CDF->fp,Attr->ADR.NumEntries);
- putint32(CDF->fp,Attr->ADR.MaxEntry);
- putint32(CDF->fp,Attr->ADR.rfuA);
- putint32(CDF->fp,Attr->ADR.rfuB);
- putint32(CDF->fp,Attr->ADR.rfuC);
- putint32(CDF->fp,Attr->ADR.rfuD);
- putint32(CDF->fp,Attr->ADR.rfuE);
-
- putbytes(CDF_ATTR_NAME_LEN, Attr->ADR.Name, CDF->fp);
-
- Entry = Attr->entryHead;
- while (Entry != NULL) {
- Seek (CDF->fp, Entry->AEDRoffset, SEEK_SET);
- putint32(CDF->fp,Entry->AEDR.RecordSize);
- putint32(CDF->fp,Entry->AEDR.RecordType);
- putint32(CDF->fp,Entry->AEDR.AEDRnext);
- putint32(CDF->fp,Entry->AEDR.AttrNum);
- putint32(CDF->fp,Entry->AEDR.DataType);
- putint32(CDF->fp,Entry->AEDR.Num);
- putint32(CDF->fp,Entry->AEDR.NumElem);
- putint32(CDF->fp,Entry->AEDR.rfuA);
- putint32(CDF->fp,Entry->AEDR.rfuB);
- putint32(CDF->fp,Entry->AEDR.rfuC);
- putint32(CDF->fp,Entry->AEDR.rfuD);
- putint32(CDF->fp,Entry->AEDR.rfuE);
-
- Nbytes = _CDFelemSizes[Entry->AEDR.DataType] * Entry->AEDR.NumElem;
-
- #if defined(sun) | defined(MIPSEB) | defined(IBMRS) | defined(HP)
- /* Do nothing. */
- #endif
-
- #if defined(vax) | defined(MIPSEL) | defined(__IBMPC__)
- if (CDF->CDR.Encoding == NETWORK_ENCODING)
- xdr_encode (Entry->AEDR.DataType, Entry->AEDR.NumElem,
- Entry->AEDR.Value, Entry->AEDR.Value);
- #endif
-
- putbytes (Nbytes, Entry->AEDR.Value, CDF->fp);
-
- Entry = Entry->entryNext;
- }
-
- Attr = Attr->attrNext;
- }
-
- return Pstatus;
- }
-